#include "esp32.h"

volatile uint8_t dma_rx[RX_MAX_FRAME_LEN] = {0};
uint8_t tx_buffer[TX_MAX_FRAME_LEN] = {0};
void usart_init(void)
{
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
    NVIC_InitType NVIC_InitStructure;
    DMA_InitType DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_USART2, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinsSource2, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinsSource3, GPIO_AF_1);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_2 | GPIO_Pins_3; // USART2 TX/RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;//GPIO_Pull_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // USART2 GPIO config

    USART_InitStructure.USART_BaudRate = 921600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure); // USART2 config

    //USART_INTConfig(USART2, USART_INT_RDNE, ENABLE);
    USART_INTConfig(USART2, USART_INT_IDLEF, ENABLE);
    USART_Cmd(USART2, ENABLE); // USART2 enable

    DMA_Reset(DMA1_Channel5);
    DMA_DefaultInitParaConfig(&DMA_InitStructure);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2 ->DT;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dma_rx;
    DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC;
    DMA_InitStructure.DMA_BufferSize = sizeof(dma_rx);
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
    DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_BYTE;
    DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE;
    DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR;
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

	USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
	DMA_ChannelEnable(DMA1_Channel5, ENABLE); // 启用DMA接收

}

void usart2_sendstr(uint8_t *str, uint16_t len)
{
    for(int i = 0; i < len; i++)
    {
		while(USART_GetFlagStatus(USART2, USART_FLAG_TDE) != SET) {}; // 等待发送完成
        USART_SendData(USART2, str[i]);
    }
	while(USART_GetFlagStatus(USART2, USART_FLAG_TRAC) != SET);
}
frame_receiver_t receiver;
operate_type_t operate_type; 
current_t current;
void esp32_init(void)
{
	usart_init();
	receiver.data_length = 0;
	receiver.frame_complete = 0;
	operate_type = OTHERS;
	current.page_addr = 0;
	current.variable_addr = 0;
	current.change_page_flag = 0;
}


void USART2_IRQHandler(void)
{
#if 1
    if( USART_GetITStatus(USART2, USART_INT_IDLEF) != RESET)
    {
		USART_ReceiveData(USART2);
        USART_ClearITPendingBit(USART2, USART_INT_IDLEF);
        receiver.data_length = sizeof(dma_rx) - DMA_GetCurrDataCounter(DMA1_Channel5);
		receiver.frame_complete = 1;
        DMA_ChannelEnable(DMA1_Channel5, DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel5, sizeof(dma_rx));
        DMA_ChannelEnable(DMA1_Channel5, ENABLE);
    }
#endif
    //处理错误标志
    if(USART_GetFlagStatus(USART2, USART_FLAG_ORERR) != RESET)
    {
        USART_ClearFlag(USART2, USART_FLAG_ORERR);
        uint8_t data = USART_ReceiveData(USART2); 
    }
}
uint8_t key_1 = 0, key_2 = 0, key_3 = 0;
uint16_t crc_test = 0;
void process_frame(void)
{
	if(receiver.frame_complete)
	{
		receiver.frame_complete = 0;
		crc_test = crc16_arr(dma_rx, 11 - 2); // 计算CRC
		
		operate_type = (operate_type_t)((dma_rx[4] << 8) | dma_rx[5]);
		switch(operate_type)
		{
			case RIGHT_ENCODER_TURN://地址0x9991,1表示慢调加，2表示慢调减去，3表示快调加，4表示快调减
				current.change_valuable_flag = 1;
				if(dma_rx[8] == 0x01)
					current.variable_value ++;
				if(dma_rx[8] == 0x02)
					current.variable_value --;
				if(dma_rx[8] == 0x03)
					current.variable_value += 10;
				if(dma_rx[8] == 0x04)
					current.variable_value -= 10;
				break;
			case LEFT_ENCODER_TURN://地址0x9992,1表示慢调加，2表示慢调减去，3表示快调加，4表示快调减
				current.change_valuable_flag = 1;
				if(dma_rx[8] == 0x01)
					current.variable_value ++;
				if(dma_rx[8] == 0x02)
					current.variable_value --;
				if(dma_rx[8] == 0x03)
					current.variable_value += 10;
				if(dma_rx[8] == 0x04)
					current.variable_value -= 10;

				break;		
			case RIGHT_ENCODER_KEY://暂定右边按键是确认，进入参数页面，设置地址0x3762,0x3763
				current.change_page_flag = 1;
				current.change_valuable_flag = 0;
				if(current.page_addr == 0x0000)	current.page_addr = 0x0002;
				else if(current.page_addr == 0x0002)	current.page_addr = 0x0003;
				else if(current.page_addr == 0x0003)	current.page_addr = 0x0002;
				current.variable_addr = 0x3760;
				break;
			case LEFT_ENCODER_KEY ://暂定左边按键是返回,进入主页面
				current.change_page_flag = 1;
				current.change_valuable_flag = 1;
				current.page_addr = 0x0000;
				current.variable_addr = 0x3760;
				if(dma_rx[8] == 0x01) key_1 ++;
				if(dma_rx[8] == 0x02) key_2 ++;
				if(dma_rx[8] == 0x03) key_3 ++;
				break;
			case RIGHT_KEY:
				if(dma_rx[8] == 0x01) 	//短按
					key_1 ++;
				if(dma_rx[8] == 0x02) 	//长按
					key_2 ++;
				
				break;
			case LEFT_KEY:
				if(dma_rx[8] == 0x01) 	//短按
					key_1 ++;
				if(dma_rx[8] == 0x02) 	//长按
					key_2 ++;
				break;
			default:
				
				break;
		}
	}
	//process_tx_sequence(&current);
}

void process_tx_sequence(current_t* current)
{
	if(current->change_page_flag)
	{
		set_page_buff(current->page_addr, tx_buffer);
		current->change_page_flag = 0;
		current->change_valuable_flag = 1;
		usart2_sendstr(tx_buffer, 30);
		return;
	}
	if(current->change_valuable_flag)
	{
		set_variable_buff(current->variable_addr, tx_buffer, current->variable_value);
		current->change_valuable_flag = 0;
		current->change_page_flag = 1;
		usart2_sendstr(tx_buffer, 30);
		return;
	}
	
}


void set_page_buff(uint16_t page_value,uint8_t* tx_buffer)
{
	uint16_t crc_ret = 0;
	tx_buffer[0] = 0x5A;
	tx_buffer[1] = 0xA5;
	tx_buffer[2] = 0x09;
	tx_buffer[3] = 0x82;
	tx_buffer[4] = 0x00;
	tx_buffer[5] = 0x84;
	tx_buffer[6] = 0x5A;
	tx_buffer[7] = 0x01;
	tx_buffer[8] = page_value >> 8;
	tx_buffer[9] = page_value & 0xff;
	crc_ret = crc16_arr(tx_buffer + 3, 7);
	tx_buffer[10] = crc_ret >> 8;
	tx_buffer[11] = crc_ret & 0xff;
}
void set_variable_buff(uint16_t variable_addr, uint8_t* tx_buffer,uint8_t variable_value)
{
	uint16_t crc_ret = 0;
	tx_buffer[0] = 0x5A;
	tx_buffer[1] = 0xA5;
	tx_buffer[2] = 0x09;
	tx_buffer[3] = 0x82;
	tx_buffer[4] = variable_addr >> 8;		//0x3760 H; start_varialbe_address
	tx_buffer[5] = variable_addr & 0xff;	//0x3760 L;
	tx_buffer[6] = variable_value >> 8;
	tx_buffer[7] = variable_value & 0xff;
	tx_buffer[8] = 0x00;
	//tx_buffer[9] = 0x00;
	//tx_buffer[10] = 0x00;
	crc_ret = crc16_arr(tx_buffer + 3, 7);
	tx_buffer[10] = crc_ret >> 8;
	tx_buffer[11] = crc_ret & 0xff;
}


void set_tx_buffer(uint16_t page_value, uint16_t variable_addr,uint8_t* tx_buffer,uint8_t variable_value)
{
	uint16_t crc_ret = 0;
	tx_buffer[0] = 0x5A;
	tx_buffer[1] = 0xA5;
	tx_buffer[2] = 0x09;
	tx_buffer[3] = 0x82;
	tx_buffer[4] = 0x00;
	tx_buffer[5] = 0x84;
	tx_buffer[6] = 0x5A;
	tx_buffer[7] = 0x01;
	tx_buffer[8] = page_value >> 8;
	tx_buffer[9] = page_value & 0xff;
	crc_ret = crc16_arr(tx_buffer + 3, 7);
	tx_buffer[10] = crc_ret >> 8;
	tx_buffer[11] = crc_ret & 0xff;
	tx_buffer[12] = 0x5A;
	tx_buffer[13] = 0xA5;
	tx_buffer[14] = 0x09;
	tx_buffer[15] = 0x82;
	tx_buffer[16] = variable_addr >> 8;
	tx_buffer[17] = variable_addr & 0xff;
	tx_buffer[18] = variable_value >> 8;
	tx_buffer[19] = variable_value & 0xff;
	tx_buffer[20] = 0x00;
	tx_buffer[21] = 0x00;
	crc_ret = crc16_arr(tx_buffer + 15, 7);
	tx_buffer[22] = crc_ret >> 8;
	tx_buffer[23] = crc_ret & 0xff;

//	tx_buffer[0] = 0x5A;
//	tx_buffer[1] = 0xA5;
//	tx_buffer[2] = 0x07;
//	tx_buffer[3] = 0x82;
//	tx_buffer[4] = 0x99;
//	tx_buffer[5] = 0x91;
//	tx_buffer[6] = 0x00;
//	if(tx_buffer[7] == 0x04)  tx_buffer[7] = 0x05;
//				else tx_buffer[7] = 0x04;
//	//tx_buffer[7] = 0x04;
////	tx_buffer[8] = 0x00;
////	tx_buffer[9] = 0x04;
//	crc_ret = crc16_arr(tx_buffer + 3, 5);
//	tx_buffer[8] = crc_ret >> 8;
//	tx_buffer[9] = crc_ret & 0xff;
	
}

//const uint16_t variable_flag_buf[12] = {0x3760,0x3761,0x3762,0x3763,0x3764,0x3765,		//表示变量地址
//								0x3766,0x3767,0x3768,0x3769,0x376A,0x376B};			//表示对应的变量标志
//static uint8_t variable_flag_count = 0;
//static all_variable_t all_variable = {0};
//const uint8_t variable_buf[6] = {all_variable.variable_3760, all_variable






